home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / xcoral / xcoral.lha / xcoral-1.72 / main_buffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-23  |  18.5 KB  |  1,032 lines

  1. /*
  2. ** Copyright 1989, 1992 by Lionel Fournigault
  3. **
  4. ** Permission to use, copy, and distribute for non-commercial purposes,
  5. ** is hereby granted without fee, providing that the above copyright
  6. ** notice appear in all copies and that both the copyright notice and this
  7. ** permission notice appear in supporting documentation.
  8. ** The software may be modified for your own purposes, but modified versions
  9. ** may not be distributed.
  10. ** This software is provided "as is" without any expressed or implied warranty.
  11. **
  12. **
  13. */
  14.  
  15. #include <stdio.h>
  16. #ifndef apollo
  17. #include <malloc.h>
  18. #endif
  19. #include <string.h>
  20.  
  21. #include "buffer.h"
  22.  
  23. static void MoreBuffer ();
  24. static int HoleSize ();
  25.  
  26. #ifdef DEBUG
  27. static void StatBuf ();
  28. #endif
  29.  
  30. /*
  31. **    Les fonctions suivantes creent et manipulent
  32. **    un buffer a bulle. La structure de celui-ci
  33. **    est illustree ci-dessous.
  34. **    
  35. **    turlututu chapeau pointu
  36. **            ^
  37. **           |
  38. **        curseur
  39. **
  40. **    turlutu_............._tu chapeau pointu
  41. **     ^      ^             ^                ^
  42. **     |      |             |                |
  43. **    top   l_cur          r_cur           bottom
  44. **    
  45.  */
  46.  
  47. /*
  48. **    Function name : GetBuffer
  49. **
  50. **    Description : Retourne une structure Buf contenant
  51. **        les pointeurs suivants :
  52. **            l_cur, r_cur : position de la bulle.
  53. **            top : le debut du buffer
  54. **            bottom : la fin du buffer
  55. **
  56. **    Input : la taille souhaitee pour le buffer.
  57. **    Ouput : Un pointeur sur Buf.
  58. */
  59. Buf *GetBuffer ( size )
  60.     register unsigned int size;
  61. {
  62.     Buf    *buf;
  63.  
  64.     buf = (Buf *) malloc ((unsigned) sizeof (Buf));
  65.  
  66.     /* 
  67.      * Alloue la place necessaire pour le buffer.
  68.      */
  69.     if ( size <= 0 ) size = SIZEOF_BUFFER;
  70.     buf -> top = ( char * ) malloc ( size );
  71.     if ( buf -> top == 0 ) 
  72.         return ( ( Buf *) 0 );
  73.     /*
  74.      * Positionne la bulle initiale.
  75.      */    
  76.     buf -> l_cur = buf -> top;
  77.     buf -> bottom = buf -> top  + ( size - 1 );
  78.     buf -> r_cur = buf -> bottom;
  79.     
  80.     return ( buf );
  81. }
  82.  
  83.  
  84. /*
  85. **    Function name : DeleteBuffer
  86. **
  87. **    Description : Comme son nom l'indique.
  88. **
  89. **    Input : Le buffer.
  90. **    Ouput : 
  91. */
  92. void DeleteBuffer ( buf )
  93. Buf *buf;
  94. {
  95.        if ( buf -> top != 0 )
  96.         (void) free ( buf -> top );       /* Le buffer */
  97.        if ( buf != 0 )
  98.         (void) free ( (char *) buf ); /* La structure associee */
  99. }
  100.  
  101.  
  102. /*
  103. **    Function name : ClearBuffer
  104. **
  105. **    Description : Pour 'effacer' le contenu du buffer,
  106. **        il suffit de positionner les pointeurs de la
  107. **        bulle pour que celle-ci occupe tout le buffer.
  108. **
  109. **    Input : un buffer
  110. **    Ouput :
  111. */
  112. void ClearBuffer ( buf )
  113. Buf *buf;
  114. {
  115.     buf -> l_cur = buf -> top;
  116.     buf -> r_cur = buf -> bottom;
  117. }
  118.  
  119.  
  120. /*
  121. **    Function name : MoreBuffer
  122. **
  123. **    Description : Augmente la taille du buffer.
  124. **
  125. **    Input : un buffer, n bytes
  126. **    Ouput :
  127. */
  128. static void MoreBuffer ( buf, n )
  129. Buf *buf;
  130. register int n;
  131. {
  132.     register int size, r_size, l_size;
  133.     char *b;
  134.  
  135.     /*
  136.      * Sauvegarde du contexte
  137.      */
  138.     l_size = buf -> l_cur - buf -> top;
  139.     r_size = buf -> bottom - buf -> r_cur;
  140.     
  141.     /*
  142.      * Calcul de la nouvelle taille
  143.      */
  144.     size = (( buf -> bottom - buf -> top + 1 + n ) / PSIZE  + 1 ) * PSIZE;
  145. #ifdef DEBUG
  146.     (void) fprintf ( stderr, 
  147.         "More buffer l_size = %d r_size = %d size = %d\n", 
  148.         l_size, r_size, size );
  149. #endif
  150.     /*
  151.      * Le nouveau buffer
  152.      */
  153.     if ( (b = ( char * ) malloc ( (unsigned) size )) == 0 )
  154.         (void) fprintf ( stderr, "Malloc error\n" );
  155.  
  156.     /* 
  157.      * On recopie l'ancien contexte
  158.      */
  159.     if ( l_size != 0 )
  160.         bcopy ( buf -> top, b, l_size );
  161.     if ( r_size != 0 )
  162.         bcopy ( buf -> r_cur, b + ( size - 1 ) - r_size, r_size );
  163.     
  164.     /*
  165.      * Liberation de l'ancien buffer
  166.      */
  167.     if ( buf -> top != 0 )
  168.         (void) free ( (char *) buf -> top ); 
  169.  
  170.     /*
  171.      * On positionne les nouveaux pointeurs
  172.      */
  173.     buf -> top = b;
  174.     buf -> l_cur = buf -> top + l_size;
  175.     buf -> bottom = buf -> top + ( size - 1 );
  176.     buf -> r_cur = buf -> bottom - r_size;
  177. #ifdef DEBUG
  178.     StatBuf ( buf );
  179. #endif
  180. }
  181.  
  182.  
  183. /*
  184. **    Function name : HoleSize
  185. **
  186. **    Description : Quelle est la place disponible dans
  187. **        le buffer.
  188. **
  189. **    Input : Le buffer
  190. **    Ouput : Retourne en octets l'espace libre.
  191. */
  192. static int HoleSize ( buf )
  193. Buf *buf;
  194. {
  195.     return ( buf -> r_cur - buf -> l_cur + 1 );
  196. }
  197.  
  198.  
  199. /*
  200. **    Function name : LoadFileInBuffer
  201. **
  202. **    Description : Copie le fichier, reference par fd, dans
  203. **        le buffer
  204. **
  205. **    Input : Le buffer, le fichier, la taille en octects
  206. **        du fichier, un flag
  207. **    Ouput : 0 si Ok ou -1 si problemes
  208. */
  209. int LoadFileInBuffer ( buf, fd, len, flag )
  210.     Buf         *buf;
  211.     FILE        *fd;
  212.     register int     len, flag;
  213. {
  214.     register char   *pp;
  215.  
  216.     /*
  217.      * L'espace libre est-il suffisant ?
  218.      */
  219.     if ( HoleSize ( buf ) < len ) {
  220.         MoreBuffer ( buf, len );
  221.     }
  222.  
  223.     /*
  224.      * Le fichier est-il a inserer dans le buffer
  225.      * ou pas ?
  226.      */
  227.     if ( flag == NEW ) {
  228.         pp = buf -> bottom - len + 1;
  229.         buf -> l_cur = buf -> top;
  230.         buf -> r_cur = buf -> bottom - len;
  231.     }
  232.     else { /* Insert */
  233.         pp = buf -> r_cur - len + 1;
  234.         buf -> r_cur -= len;
  235.     }
  236.     
  237.     /* 
  238.      * Copie
  239.      */
  240.     while ( len >= PSIZE ) {
  241.         if ( fread( pp, PSIZE, 1, fd) != 1 ) {
  242.             perror("Read error\n");
  243.             return ( -1 );
  244.             }
  245.         len -= PSIZE;
  246.         pp += PSIZE;
  247.     }
  248.     if (len) {
  249.         if ( fread ( pp, len, 1, fd ) != 1 ) {
  250.             perror ("Read error\n");
  251.             return ( -1 );
  252.         }
  253.     }
  254. #ifdef DEBUG
  255.     StatBuf ( buf );
  256. #endif
  257.     return 0;
  258. }
  259.  
  260.  
  261. /*
  262. **    Function name : WriteCurrentFile
  263. **
  264. **    Description : Copie du buffer dans le fichier reference
  265. **        par df.
  266. **
  267. **    Input : Le buffer, le fichier
  268. **    Ouput : La taille en octets du fichier.
  269. */
  270. int WriteCurrentFile ( buf, fd )
  271.     Buf *buf;
  272.     FILE *fd;
  273. {
  274.     /* 
  275.      * La taille des parties droite et gauche
  276.      * (de part et d'autre du curseur).
  277.      */
  278.     register int l_size = buf -> l_cur - buf -> top;
  279.     register int r_size = buf -> bottom - buf -> r_cur;
  280.  
  281.     /*
  282.      * Ecriture partie gauche
  283.      */
  284.     if ( l_size ) {
  285. #ifdef DEBUG
  286.     (void) fprintf ( stderr, "l_size = %d\n", l_size );
  287. #endif
  288.         if ( fwrite ( buf -> top, l_size, 1, fd ) != 1 ) {
  289.             perror ( "Write error\n" );
  290.             return (-1);
  291.         }
  292.     }
  293.     /*
  294.      * Ecriture partie droite
  295.      */
  296.     if ( r_size ) {
  297. #ifdef DEBUG
  298.     (void) fprintf ( stderr, "r_size = %d\n", r_size );
  299. #endif
  300.         if ( fwrite ( buf -> r_cur + 1, r_size, 1, fd ) != 1 ) {
  301.             perror ( "Write error\n" );
  302.             return (-1);
  303.         }
  304.     }
  305.     return ( l_size + r_size );
  306. }
  307.  
  308.  
  309. /*
  310. **    Function name : MoveToLine
  311. **
  312. **    Description : Deplacement a la ligne n.
  313. **        L'argument n est relatif par rappor a la
  314. **        ligne courante (e.g -1 ligne precedante).
  315. **
  316. **    Input : Le buffer, ligne
  317. **    Ouput : 0 si OK ou -1 si problemes.
  318. */
  319. int MoveToLine ( buf, n )
  320.     Buf *buf;
  321.     register int n;
  322. {
  323.     int len = 0;
  324.  
  325.     if (n == 0)
  326.         return 0;
  327.  
  328.     /*
  329.      * Just pour avoir la longueur du deplacement
  330.      */
  331.     if ( n > 0 ) 
  332.         (void)  GetForwardLine ( buf, n, &len );
  333.     else
  334.         (void)  GetBackwardLine ( buf, n, &len );
  335.  
  336.     if ( ! len )
  337.         return -1;
  338.  
  339.     if ( MoveHole ( buf, len ) == -1 ) {
  340.            (void) fprintf ( stderr, "Internal Error 6\n" );
  341.         return -1;
  342.      }
  343.     else
  344.         return 0;
  345. }
  346.  
  347.  
  348. /*
  349. **    Function name : MoveHole
  350. **
  351. **    Description : Deplacement de la bulle de n octets
  352. **
  353. **    Input : Le buffer, n octets.
  354. **    Ouput : 0 si OK ou -1 si problemes.
  355. */
  356. int MoveHole ( buf, n )
  357.     register Buf *buf;
  358.     register int n;
  359. {
  360.     if ( n == 0 ) {
  361. #ifdef DEBUG
  362.       (void) fprintf ( stderr, "n = 0\n" );
  363. #endif
  364.         return 0;
  365.     }
  366.  
  367.     /*
  368.      * Deplacement a droite
  369.      */
  370.     if ( n > 0 ) {
  371.         /*
  372.          * Va-t on aux fraises ?
  373.          */
  374.         if ( buf -> r_cur + n > buf -> bottom )  
  375.              return (-1);
  376.         /*
  377.          * 1 octet seulement.
  378.          */
  379.         if ( n == 1 ) {
  380.             buf -> r_cur ++;
  381.             *buf -> l_cur = *buf -> r_cur;
  382.             buf -> l_cur ++;
  383. #ifdef DEBUG
  384.              StatBuf ( buf );
  385. #endif
  386.             return 0;
  387.         }
  388.  
  389.         /*
  390.          * Plusieurs caracteres
  391.          */
  392.         bcopy ( buf -> r_cur + 1, buf -> l_cur, n );
  393.         buf -> r_cur += n;
  394.         buf -> l_cur += n;
  395. #ifdef DEBUG
  396.         StatBuf ( buf );
  397. #endif
  398.     }
  399.  
  400.     /*
  401.      * Deplacement a gauche.
  402.      */
  403.     else {
  404.         if ( buf -> l_cur - ( - n ) < buf -> top )
  405.             return ( -1 );
  406. #ifdef DEBUG
  407.          (void) fprintf ( stderr, "Left Move n = %d\n", n );
  408. #endif
  409.         if ( n == -1 ) {
  410.             buf -> l_cur --;
  411.             *buf -> r_cur = *buf -> l_cur;
  412.             buf -> r_cur --;
  413. #ifdef DEBUG
  414.             StatBuf ( buf );
  415. #endif
  416.             return 0;
  417.           }
  418.         buf -> l_cur -= ( -n );
  419.         buf -> r_cur -= ( -n );
  420.         bcopy ( buf -> l_cur, buf -> r_cur + 1 , -n );
  421.  
  422. #ifdef DEBUG
  423.         StatBuf ( buf );
  424. #endif
  425.     }
  426.     return 0;
  427. }
  428.  
  429.  
  430. /*
  431. **    Function name : StatBuf
  432. **
  433. **    Description : Pour le mode DEBUG. Imprime les infos.
  434. **
  435. **    Input : Le buffer
  436. **    Ouput :
  437. */
  438. #ifdef DEBUG
  439. static void StatBuf ( buf )
  440.     Buf *buf;
  441. {
  442.       (void) fprintf ( stderr, 
  443.         "Hole : buf = %d top = %d bottom = %d l_cur = %d r_cur = %d\n", 
  444.            buf, buf -> top, buf -> bottom, buf -> l_cur, buf -> r_cur );
  445. }
  446. #endif
  447.  
  448.  
  449. /*
  450. **    Function name : HoleToRight
  451. **
  452. **    Description : Deplacement de la bulle completement
  453. **        a droite. Cela revient a deplacer le curseur
  454. **        en fin de buffer.
  455. **
  456. **    Input : Le buffer
  457. **    Ouput :
  458. */
  459. void HoleToRight ( buf )
  460.     Buf *buf;
  461. {
  462.  
  463. #ifdef DEBUG
  464.       (void) fprintf ( stderr, "HoleToRight\n" );
  465. #endif
  466.  
  467.       if ( MoveHole ( buf, buf -> bottom - buf -> r_cur ) == -1 )
  468.         (void) fprintf ( stderr,"Internal Error 7...\n" );
  469. }
  470.  
  471.  
  472. /*
  473. **    Function name : HoleToLeft
  474. **
  475. **    Description : Deplacement de la bulle completement
  476. **        a gauche. Cela revient a deplacer le curseur
  477. **        au debut du buffer.
  478. **
  479. **    Input : Le buffer
  480. **    Ouput :
  481. */
  482. void HoleToLeft ( buf )
  483.     Buf *buf;
  484. {
  485.  
  486. #ifdef DEBUG
  487.       (void) fprintf ( stderr, "HoleToleft\n" );
  488. #endif
  489.  
  490.     if ( MoveHole ( buf, buf -> top - buf -> l_cur ) == -1 )
  491.         (void) fprintf ( stderr, "Internal Error 8...\n" );    
  492. }
  493.  
  494.  
  495. /*
  496. **    Function name : InsertNchar
  497. **
  498. **    Description : Insere n caracteres a partir de la 
  499. **        position courante.
  500. **
  501. **    Input : Le buffer, chaine a inserer, sa taille.
  502. **    Ouput : 
  503. */
  504. void InsertNchar ( buf, s, n )
  505.     Buf *buf;
  506.     register char *s;
  507.     register int n;
  508. {
  509.     /*
  510.      * Reste-il de la place ?
  511.      */
  512.     if ( HoleSize ( buf ) < n ) {
  513.         (void) MoreBuffer ( buf, n );
  514.     }
  515.             
  516.     if ( n == 1 ) {
  517.         *buf -> l_cur = *s;
  518.         buf -> l_cur ++;
  519.         return;
  520.     }
  521.  
  522.        bcopy ( s, buf -> l_cur, n );
  523.     buf -> l_cur += n;
  524.     return;
  525. }
  526.  
  527.  
  528. /*
  529. **    Function name : DeleteNchar
  530. **
  531. **    Description : Efface n caracteres a partir de la 
  532. **        position courante.
  533. **
  534. **    Input : Le buffer, nb de caracteres a effacer.
  535. **    Ouput :
  536. */
  537. void DeleteNchar ( buf, n )
  538.     Buf *buf;
  539.     register int n;
  540. {
  541.  
  542. #ifdef DEBUG
  543.     (void) fprintf ( stderr, "Delete n = %d\n", n );
  544. #endif
  545.  
  546.        if ( buf -> l_cur <= buf -> top )
  547.               return;
  548.  
  549.        if ( buf -> l_cur == buf -> r_cur )
  550.         (void) fprintf ( stderr, "End of buf\n" );
  551.        buf -> l_cur -= n;
  552. }
  553.  
  554.  
  555. /*
  556. **    Function name : GetForwardLine
  557. **
  558. **    Description : Recherche a partir de la position 
  559. **        courante, le debut de la n-ieme ligne
  560. **          
  561. **    Input : Le buffer, no ligne, deplacement ( il
  562. **        s'agit du nombres de caracteres entre
  563. **        la position courante et la position
  564. **        recherchee );
  565. **    Ouput : pointeur sur n-ieme ligne ou 0 si problemes.
  566. */
  567. char *GetForwardLine ( buf, n, len )
  568.     register Buf *buf;
  569.     register int n;
  570.     register int *len;    /* Return */
  571.  
  572. {
  573.     register char *p;
  574.     register int i = 0;
  575.  
  576.     p = buf -> r_cur + 1 ;
  577.  
  578.     while ( p <= buf -> bottom ) { 
  579.         if ( *p == '\n' )
  580.             n--;
  581.         if ( n == 0 ) {
  582.             if ( p == buf -> bottom ) {
  583.                 *len = ++i;
  584.                 return 0;
  585.             }
  586.             else {
  587.                 *len = ++i;
  588.                 return ++p;
  589.             }
  590.         }
  591.         p++;
  592.         i++;
  593.     }
  594.     return 0;
  595. }
  596.  
  597.  
  598. /*
  599. **    Function name : GetBackwardLine
  600. **
  601. **    Description : Recherche a partir de la position 
  602. **        courante, le debut de la n-ieme ligne
  603. **          
  604. **    Input : Le buffer, no ligne, deplacement ( il
  605. **        s'agit du nombres de caracteres entre
  606. **        la position courante et la position
  607. **        recherchee );
  608. **    Ouput : pointeur sur n-ieme ligne ou 0.
  609. */
  610. char *GetBackwardLine ( buf, n, len )
  611.     register Buf *buf;
  612.     register int n;
  613.     register int *len; /* Return */
  614. {
  615.     register char *p;
  616.     register int i = 0;
  617.  
  618.     p = buf -> l_cur - 1;
  619.     n --;
  620.     while ( p > buf -> top ) {
  621.         if ( *p == '\n' ) n++;
  622.         if ( n == 0 ) {
  623.             *len = - ( i );
  624.             return ++p;
  625.         }
  626.         p--;
  627.         i++;
  628.     }
  629.     /* Debut du buffer */
  630.  
  631.     if ( (n <= -2) && (*buf -> top != '\n') ) {
  632.         *len = 0;
  633.         return 0;
  634.     }
  635.     if ( (n < -2) && (*buf -> top == '\n') ) {
  636.         *len = 0;
  637.         return 0;
  638.     }
  639.     /* Cas special si 1 ere ligne vide */
  640.     if ( (*buf -> top == '\n') && (n == -1) ) {
  641.         *len = -i;
  642.         return ++p;
  643.     }
  644.     else {
  645.         *len = - (i+1);
  646.         return p;
  647.     }
  648. }
  649.  
  650.  
  651. /*
  652. **    Function name : GetCurrentLine
  653. **
  654. **    Description : Assemblage de la ligne courante.
  655. **        Cette fonction est le coeur de l'application.
  656. **        
  657. **    Input : Le buffer, la taille (return)
  658. **    Ouput : Le pointeur sur la ligne courante.
  659. */
  660. char *GetCurrentLine ( buf, len )
  661.     register Buf *buf;
  662.     register int *len; /* Return */
  663. {
  664. #define MAX_SLEN    64
  665.     static int mbuf_len = 0;
  666.     static char sbuf [MAX_SLEN], *mbuf, *mbuf_save = 0;
  667.     register int i, j;
  668.     register char *p, *pp;
  669.  
  670.     *len = 0;
  671.     /*
  672.      * Partie gauche : positionnement du pointeur et calcul
  673.      *    du deplacement par rapport a la position
  674.      *    courante.
  675.      */
  676.     p = buf -> l_cur - 1;
  677.     j = 0;
  678.     while ( p > buf -> top ) {
  679.         if ( *p == '\n' )
  680.             break;
  681.         p--;
  682.         j++;
  683.     }
  684.     if ( p != buf -> top )
  685.         p++;
  686.     else {    
  687.         /*
  688.          * Debut du buffer
  689.          */
  690.         if ( *p != '\n' ) 
  691.             j++;
  692.         else
  693.             /*
  694.              * 1er ligne : vide
  695.              */
  696.             p++;
  697.     }
  698.     *len = j;
  699.  
  700.     /*
  701.      * On garde p pour plus tard
  702.      */
  703.     pp = p;
  704. #ifdef DEBUG
  705.     (void) fprintf ( stderr, 
  706.         "len = %d Left side s = %s\n", *len, sbuf );
  707. #endif
  708.     /*
  709.      * Partie droite : positionnement du pointeur et calcul
  710.      *    du deplacement par rapport a la position
  711.      *    courante.
  712.      */
  713.     p = buf -> r_cur + 1;
  714.     i = 0;
  715.     while ( p < buf -> bottom ) {
  716.         if ( *p == '\n' )
  717.             break;
  718.         p++;
  719.         i++;
  720.     }
  721.     /*
  722.      * On teste si la longueur de la ligne est > a MAX_SLEN.
  723.      */
  724.     if ( ( i + j + 8 ) > MAX_SLEN ) {
  725.         /*
  726.          * Il faut de la place
  727.          */
  728.         if ( mbuf_save ) {
  729.             /*
  730.              * Si le buffer deja alloue est assez grand on prend
  731.              * celui-ci, sinon on en alloue un autre.
  732.              */
  733.             if (( i + j + 8 ) > mbuf_len) {
  734.                          if ( mbuf_save != 0 )
  735.                     (void) free ( mbuf_save );
  736.                 mbuf_len = ( 2 * ( i + j + 8 ));
  737.                 mbuf = ( char *) malloc ( (unsigned int) mbuf_len );
  738.                 mbuf_save = mbuf;
  739.             }
  740.             else
  741.                 mbuf = mbuf_save;
  742.         }
  743.         else {
  744.             mbuf_len = i + j + 8;
  745.             mbuf = ( char *) malloc ( (unsigned int) mbuf_len );
  746.             mbuf_save = mbuf;
  747.         }
  748.         bzero ( mbuf, mbuf_len  );
  749.     }
  750.     else {
  751.         /*
  752.          * On se sert du buffer static
  753.          */
  754.         bzero ( sbuf, MAX_SLEN );
  755.         mbuf = sbuf;
  756.     }
  757.     /*
  758.      * On copie la partie gauche
  759.      */
  760.     (void) strncpy ( mbuf, pp, j );
  761.     j = 0;
  762.     
  763.     /*
  764.      * Fin du buffer et pas de retour chariot
  765.      */
  766.     if ( (p == buf -> bottom) && (*p != '\n') ) {
  767.         *len += 1;
  768.         /*
  769.          * On ajoute la partie droite
  770.          */
  771.         (void) strncat ( mbuf, p - i, i + 1 );
  772.         j = 1;
  773.     }
  774.     else
  775.         /*
  776.          * On ajoute la partie droite
  777.          */
  778.         (void) strncat ( mbuf, p - i, i );
  779.  
  780.     *len += i;
  781.     (void) strncat ( mbuf, "\n", 1 ); 
  782. #ifdef DEBUG
  783.     (void) fprintf ( stderr,
  784.         "i = %d len = %d Current line : %s\n", i, *len, mbuf );
  785.     (void) fprintf ( stderr, "Deplace = %d\n", i+1 );
  786. #endif
  787.     return mbuf;
  788. }
  789.  
  790.  
  791. /*
  792. **    Function name : GetNcFromLeft
  793. **
  794. **    Description : Recherche le debut de la ligne
  795. **        courante.
  796. **
  797. **    Input : Le buffer
  798. **    Ouput : Le nombre de caracteres pour aller en debut
  799. **        de ligne.
  800. */
  801. int GetNcFromLeft ( buf )
  802.     Buf *buf;
  803. {
  804.        register int n = 0;
  805.        register char *p = buf -> l_cur - 1;
  806.  
  807.        while ( p > buf -> top ) {
  808.               if ( *p == '\n' )
  809.                  break;
  810.           p--;
  811.           n++;
  812.        }
  813.  
  814.        /*
  815.      * Est-ce la 1 ere ligne et traitement
  816.      * du cas ou celle-ci est vide
  817.      */
  818.        if ( (p == buf -> top) && (*p != '\n') )
  819.               n++;
  820.        return n;
  821. }
  822.  
  823.  
  824. /*
  825. **    Function name : GetNcFromRight
  826. **
  827. **    Description : Recherche de la fin de ligne.
  828. **
  829. **    Input : Le buffer
  830. **    Ouput : Le nombre de caracteres pour aller en fin
  831. **        de ligne (le '\n' n'est pas compte).
  832. */
  833. int GetNcFromRight ( buf )
  834.     Buf *buf;
  835. {
  836.        register int n = 0;
  837.        register char *p = buf -> r_cur + 1;
  838.  
  839.        while ( p < buf -> bottom ) {
  840.               if ( *p == '\n' ) {
  841.             break;
  842.           }
  843.           p++;
  844.           n++;
  845.        }
  846.        if ( (p == buf -> bottom) && (*p != '\n') ) {
  847.           n++;
  848.         }
  849.        return n;
  850. }
  851.  
  852.  
  853. /*
  854. **    Function name : GetNumberOfLineInBuf
  855. **
  856. **    Description : Combien de lignes dans le buffer.
  857. **
  858. **    Input : Le buffer
  859. **    Ouput : Le nombre de lignes.
  860. */
  861. int GetNumberOfLineInBuf ( buf )
  862.     Buf *buf;
  863. {
  864.     register int n = 1;
  865.     register char *p = buf -> top;
  866.  
  867.     /*
  868.      * Partie gauche
  869.      */
  870.     while ( p < buf -> l_cur ) {
  871.         if ( *p == '\n' )
  872.             n++;
  873.         p++;
  874.     }
  875.     
  876.     /*
  877.      * Partie droite
  878.      */
  879.     p = buf -> r_cur + 1;
  880.     while ( p < buf -> bottom ) {
  881.         if ( *p == '\n' )
  882.             n++;
  883.         p++;
  884.     }
  885.  
  886.     /*
  887.      * Traitement du '\n' en fin de buffer
  888.      */
  889.     if ( (buf -> bottom != buf -> r_cur)
  890.         && (*(buf -> bottom) == '\n' ))
  891.         n++;
  892.  
  893. #ifdef DEBUG
  894.     (void) fprintf ( stderr, " nb lines = %d\n", n );
  895. #endif
  896.  
  897.        return n;
  898. }
  899.  
  900.  
  901. /*
  902. **    Function name : GetNewLine
  903. **
  904. **    Description : Recherche dans un chaine de longueur
  905. **        donnee, le nombre de ligne.
  906. **
  907. **    Input : La chaine, la longueur de celle-ci.
  908. **    Ouput : Le nombre de 'new_line'
  909. */
  910. int GetNewLine ( t, len )
  911.     register char *t; /* le texte */
  912.     register int len; /* la longeur du texte */
  913. {
  914.     register char *start = t;
  915.     register int nl = 0;
  916.  
  917.     if ( len == 0 ) return nl;
  918.  
  919.     if ( len > 0 ) {
  920.         while ( t < (start + len) ) {
  921.             if ( *t == '\n' ) nl++;
  922.             t++;
  923.         }
  924.         return nl;
  925.     }
  926.     else {
  927.         while ( t > (start + len) ) {
  928.             if ( *t == '\n' ) nl++;
  929.             t--;
  930.         }
  931.         return nl;
  932.     }
  933. }
  934.  
  935.  
  936. /*
  937. **    Function name : GetCurrentChar
  938. **
  939. **    Description : Donne le caractere courant.
  940. **
  941. **    Input : Le buffer
  942. **    Ouput :
  943. */
  944. void GetCurrentChar ( buf, c )
  945. Buf *buf;
  946. register char *c; /* Return */
  947. {
  948.     if ( (buf -> r_cur) == buf -> bottom )
  949.         *c  = '\0';
  950.     else
  951.         (void) strncpy ( c, buf -> r_cur + 1, 1 );
  952. }
  953.  
  954.  
  955. /*
  956. **    Function name : GetPrevChar
  957. **
  958. **    Description : Donne le caractere precedent.
  959. **
  960. **    Input : Le buffer
  961. **    Ouput :
  962. */
  963. void GetPrevChar ( buf, c )
  964. Buf *buf;
  965. register char *c;
  966. {
  967.        if ( buf -> l_cur <= buf -> top )
  968.               *c = '\0';
  969.        else
  970.           (void) strncpy ( c, buf -> l_cur -1, 1 );
  971. }
  972.  
  973.  
  974. /*
  975. **    Function name : DeleteLines
  976. **
  977. **    Description : Efface n lines a partir de la position courante.
  978. **        Positionne le nombre de caracteres et de lignes
  979. **        effectivement effacees. Comme toujours les resultats ne
  980. **        sont pas les memes suivant que le buffer se termine
  981. **        ou non par un new-line.
  982. **    Input : Le buffer
  983. **    Ouput : Position courante ( curseur droit ) apres effacement
  984. **        des lignes
  985. */
  986. char *DeleteLines ( buf, n, len, dn )
  987.     Buf *buf;
  988.     register int n;      /* nb lignes demandees */
  989.     register int *len;   /* caracteres deletes (return) */
  990.     register int *dn;    /* nb lignes deletees (return) */
  991. {
  992.     register int i = 0;
  993.     register int end_line = 0;
  994.     register char *p = buf -> r_cur + 1;
  995.  
  996.     if ( n == 0 ) return 0;
  997.     if ( n == 1 ) end_line = 1;
  998.  
  999.     *dn = 0;
  1000.  
  1001.     if ( n > 1 ) 
  1002.         i++;
  1003.  
  1004.     while ( p < buf -> bottom ) {
  1005.         if ( *p == '\n' ) {
  1006.             n --;
  1007.             (*dn) ++;
  1008.         }
  1009.         if ( n == 0 ) {
  1010.             if ( end_line == 1 ) {  /* Delete end of line */
  1011.                 *dn = 0;
  1012.                 if ( (*p == '\n') && (i == 0)) { /* Ligne vide */
  1013.                     *dn = i = 1;;
  1014.                 }
  1015.             }
  1016.             break;
  1017.         }
  1018.         i ++;
  1019.         p++;
  1020.     }
  1021.     if ( p == buf -> bottom ) {  /* Fin du buffer */
  1022.         if ( end_line == 0 )     /* Plusieurs lignes */
  1023.             (*dn) ++; 
  1024.         if ( (end_line == 1) && ( *p != '\n' ) )
  1025.             i++;
  1026.     }
  1027.     p = buf -> r_cur + 1;
  1028.     buf -> r_cur += i;
  1029.     *len = i;
  1030.     return p;
  1031. }
  1032.